Detecting Open Cities in Your Mod
---------------------------------

If you have a mod which does things in the cities, you may desire to support users who install Open Cities. In order to facilitate this, there are two methods available which can be combined if necessary.

Using a Script
--------------

Newer methods employing OBSE make most of this largely obsolete in light of the ismodloaded function, but since I like to allow people who can't/won't use OBSE the ability to use Open Cities, it seems like a good idea to keep this method documented.

This method has existed since the original Open Cities mod was released. Back then only one item was chosen since the cities were not modular. Each city has one persistent object that was chosen. These are all present in Oblivion.esm in the stock worldspaces. Yes, I'm aware that Benirus Manor is a building. It was also the only thing I could find at the time that was persistent, resizeable, and stock.

Sizes to check for in Open Cities Classic:

Anvil: BenirusManorExteriorHauntedRef = 1.01
Bravil: NordinorsIllegalsStuffRef = 1.01
Bruma: JerallViewTriggerRef = 1.01
Cheydinhal: NewlandsLodgeTriggerRef = 1.01
Chorrol: ChorrolForSaleSignRef = 1.01
Leyawiin: LeyawiinForSaleRef = 1.01
Skingrad: SleepingMatAmuseiSkingrad = 1.01
Outer Districts: Dark09Bench2 = 1.01
New Sheoth: SERoofTopChair1Ref = 1.01

Sizes to check for in Open Cities Reborn:

Anvil: BenirusManorExteriorHauntedRef = 0.75
Bravil: NordinorsIllegalsStuffRef = 1.01 (doesn't need a different one as its layout remains unchanged)
Bruma: JerallViewTriggerRef = 0.75
Cheydinhal: NewlandsLodgeTriggerRef = 0.75
Chorrol: ChorrolForSaleSignRef = 0.75
Leyawiin: LeyawiinForSaleRef = 0.75
Skingrad: SleepingMatAmuseiSkingrad = 1.01 (doesn't need a different one as its layout remains unchanged)
Outer Districts: Dark09Bench2 = 1.01 (doesn't need a different one as its layout remains unchanged)
New Sheoth: SERoofTopChair1Ref = 1.01 (doesn't need a different one as its layout remains unchanged)

Each one of these has had their size scale set to the value specified. The modifications are done to the objects in the original worldspaces, so the user never notices the alterations. The alterations reverse when OC is removed. This will allow each individual city to be detected regardless of whether the others are present or not. Any combination of these is also possible. So if your mod alters Anvil and Bruma, then you can check for both to see if the open versions are in use.

I tried to pick things that were unlikely to get deleted, I think I succeeded. Two of them are even invisible to the player under normal conditions, which suits me just fine.

A quest needs to be created that starts the game enabled, has no stages, and is assigned the script you'll be creating to monitor changes. This quest should not be visible to the player and should not be terminated. The exception to this would be if certain conditions are met in your mod and it no longer matters if OC is installed or not. At that point you should issue a "StopQuest" command in your scripts to halt it.

The script detection method has the advantage of being load order proof. So if you have a mod which must load after Open Cities and you still want to provide some kind of support for it, this method is it. This method is also the only way you can set up conditional outcomes in quests, such as alternative targets or alternative actions in result scripts.

The downside of using script detection is that it needs to run continuously to watch for changes to the monitor items.

Here's an example of how it works:

scn NAMEOFYOURSCRIPTHERE

; Adjusts things if Open Cities is present.

short UOMPOCPresent ; Change this variable name to suit
float fQuestDelayTime

Begin GameMode

	if ( UOMPOCPresent == 0 )
		set fQuestDelayTime to 61		;Only run every 61 seconds, minimizing game impact
		set UOMPOCPresent to 1
	endif

	if ( ChorrolForSaleSignRef.GetScale < 0.81 ) && ( ChorrolForSaleSignRef.GetScale > 0.79 )		; OC is present
		if UOMPOCPresent == 1
			Set UOMPOCPresent to 2
			; Things to change go here
		endif
	else
		if (  UOMPOCPresent == 2 )		; OC has been removed
			set  UOMPOCPresent to 1
			; Things to change back go here
		endif
	endif

End

Using the "Rock Method"
-----------------------

More recently, a method for detection of one mod by another was developed by Vorians and Ismelda. Instead of using a script, which needs constant monitoring, it is possible to take advantage of the parent/child relationship that objects can have and cause one mod to enable features in another as long as the proper load order is maintained. This method became known as the "rock method" because they originally used a set of rocks to make it all work.

The idea is fairly simple. The parent mod sets aside a group of items in a little used testing cell. The more isolated the items are, the better. Testing cells make perfect hosts since they don't usually get modified. These items are marked as persistent, and should be disabled. They *MUST* be items found in Oblivion.esm or this method will not work.

Trigger items for Open Cities Classic:

Anvil:      00031810
Bravil:     0003180F
Bruma:      000317EE
Cheydinhal: 0003180E
Chorrol:    00031811
Leyawiin:   000317EF
Skingrad:   000317E4
Outer Districts: 000317E8
New Sheoth: 000317EB

Trigger items for Open Cities Reborn:

Anvil:      00031800
Bravil:     0003180F (doesn't need a different one as its layout remains unchanged)
Bruma:      00031801
Cheydinhal: ?
Chorrol:    000317FC
Leyawiin:   0003180D
Skingrad:   000317E4 (doesn't need a different one as its layout remains unchanged)
Outer Districts: 000317E8 (doesn't need a different one as its layout remains unchanged)
New Sheoth: 000317EB (doesn't need a different one as its layout remains unchanged)

These items are all part of the clutter inside the Castle Varaldo interior cell which was never attached to the game world anywhere. The castle offers plenty of extra stuff to swipe if needed and this method is safer than injecting records into Oblivion.esm on the off chance that the injected formID gets reused by another mod.

Anything you have in your mod which should be toggled needs to use the listed items as their enable parent in the CS. Set the appropriate strawberry up as persistent, and initially disabled. An editor ID is probably not necessary but helps to identify the item by sight.

Objects in your mod which should be active if OC is *NOT PRESENT* should be setup with the enable state opposite of the parent. Objects which should be active when OC *IS PRESENT* should be marked as initially disabled and *NOT* opposite of the parent enable state. It does not matter if the child item is persistent or not, so you can use this to setup things like alternate doors and markers as well as normal temporary items. In fact, alternate sets of doors to enter and leave a new location are what this method is best suited for.

On my side in the Open Cities files, each trigger item has simply been assigned an editor ID so that they will override the normal item. The persistent flag will be removed, and the strawberry will be enabled. Any items set to enable when the parent does will be toggled on, and any items set to toggle off will be off.

If everything has been done correctly, the end user only needs to be sure that your mod loads before Open Cities. If your mod is designed in such a way that it has to load after Open Cities for some reason, this method will not work and you will need to fall back to the scripted method. There are other limitations on the method as well, such as being unable to use it to create alternative quest targets or conditional AI packs.

Using this method for alternative exits, you can create one set of doors that lead to the stock worldspaces, and another set of doors in the same locations that lead to the Open Cities worldspaces. This is what TIE does with the secret entrances into the cities. There are duplicate sets of exits at the appropriate locations which toggle on/off based on which cities are loaded.

Several of the compatibility patches I've produced use this method. The patch files act as surrogates for the parent mod, which is why you'll often find the load order directions specify placing it immediately following the parent mod instead of being with other OC patch files.

Cell Ownership Method
---------------------

For mods that require AI packs in cities or quest targets to point to locations in a city exterior, a second hack is needed in order to fascilitate this. It is relatively straightforward and only involves a minimal amount of extra work in order to set it up. The method involves hijacking the dummy cells for each city and giving them a specific ownership. This ownership can then be checked for using an IsCellOwner condition in AI or quest targeting. This method is immune to load order positioning and will only fail if a mod loads after Open Cities and modifies the cells in some way, which would cancel out the ownership.

You *DO NOT* change the cell ownership in your mod, all you do with this is add extra AI/Quest targets that look for the ownership changes and act accordingly. You will need to place your own markers for the added packs and targets to use though.

NPCs must be used as owners because the CS does not allow factions in the AI pack "IsCellOwner" condition. I have chosen to use the formIDs of each city's beggars.

Open Cities Classic:

Anvil Dummy Cell     : 00035682 Owner = Penniless Olvus  : 00015D7F
Bravil Dummy Cell    : 000319D9 Owner = Wretched Aia     : 00015D80
Bruma Dummy Cell     : 0003134A Owner = Jorck the Outcast: 00015D83
Cheydinhal Dummy Cell: 00030FAE Owner = Luckless Lucina  : 00015D86
Chorrol Dummy Cell   : 00024802 Owner = Nermus the Mooch : 00015D88
OuterDistricts       : 00022F4A Owner = J'baana          : 0009346E
Leyawiin Dummy Cell  : 0002C79C Owner = Rancid Ra'dirsha : 00015D8A
Skingrad Dummy Cell  : 00028E70 Owner = Nigidius the Needy: 00015D8C
SKCastle Dummy Cell  : 00084476 Owner = Nigidius the Needy: 00015D8C
New Sheoth Dummy Cell: 00096626 Owner = Uungor           : 0006989C

Open Cities Reborn:

Anvil Dummy Cell     : 00035682 Owner = Imus the Dull       : 00015D82
Bravil Dummy Cell    : 000319D9 Owner = Wretched Aia        : 00015D80 (doesn't need a different one as its layout remains unchanged)
Bruma Dummy Cell     : 0003134A Owner = Fetid Jofnhild      : 00015D84
Cheydinhal Dummy Cell: 00030FAE Owner = Bruccius the Orphan : 00015D85
Chorrol Dummy Cell   : 00024802 Owner = Lazy Kaslowyn       : 00015D87
OuterDistricts       : 00022F4A Owner = J'baana             : 0009346E (doesn't need a different one as its layout remains unchanged)
Leyawiin Dummy Cell  : 0002C79C Owner = Deeh the Scalawag   : 00015D89
Skingrad Dummy Cell  : 00028E70 Owner = Nigidius the Needy  : 00015D8C (doesn't need a different one as its layout remains unchanged)
SKCastle Dummy Cell  : 00084476 Owner = Nigidius the Needy  : 00015D8C (doesn't need a different one as its layout remains unchanged)
New Sheoth Dummy Cell: 00096626 Owner = Uungor              : 00013A69 (doesn't need a different one as its layout remains unchanged)

For working examples of this system in action, refer to Heart of the Dead and Kragenirs Death Quest. Both of these mods use the cell owenership flags to determine where to send certain NPCs at various points in their quests.